define([],function (){
    class Promise {
        constructor(executor) {
            this.PromiseState = 'pending'
            this.PromiseResult = null
            // 声明属性,用于保存成功/失败的回调函数，异步情况
            this.callbacks = []
            // 保存实例对象 this 的值，这里的this指向以后对象
            const self = this
            // 声明resolve函数，使用resolve函数的时候是传入参数了，所以还要有形参
            function resolve(data) {
                // 判断状态
                if (self.PromiseState !== 'pending') {
                    return
                }
                // 1. 修改对象状态 PromiseState
                self.PromiseState = 'fulfilled'
                // 2. 设置对象结果值 PromiseResult
                self.PromiseResult = data
                // 调用成功的回调函数 ？？？ 怎么才能调用到呢？
                self.callbacks.forEach(item => {
                    item.onResolved(data)
                })
            }
            // 声明reject函数
            function reject(data) {
                // 判断状态
                if (self.PromiseState !== 'pending') {
                    return
                }
                // 1. 修改对象状态 PromiseState
                self.PromiseState = 'rejected'
                // 2. 设置对象结果值 PromiseResult
                self.PromiseResult = data
                // 执行回调
                self.callbacks.forEach(item => {
                    item.onRejected(data)
                })
            }

            // 同步调用「执行器函数」
            // 需要在执行器函数中传入两个参数，而且两个参数又都还是函数
            // 还要对 resolve 和 reject 进行声明
            try {
                executor(resolve, reject)
            } catch (err) {
                // err 就是使用的时候throw抛出的错误
                // 修改 promise对象状态为失败
                reject(err)
            }
        }

        then(onResolved, onRejected) {
            const self = this
            if (typeof onRejected !== 'function') {
                // 如果不传递onRejected，我们给个默认处理，抛出异常
                // 这个容错处理，不仅解决了undefined问题，更是解决了穿透问题
                // 相当于是给每个then提供了一个默认的onRejected函数
                onRejected = reason => {
                    throw reason
                }
            }
            // 同理，如果使用的时候没传onResolved，我们也可以指定一个默认的处理方式
            if (typeof onResolved !== 'function') {
                onResolved = value => value
            }
            return new Promise((resolve, reject) => {
                function callback(type) {
                    try {
                        let result = type(self.PromiseResult)
                        // 判断
                        if (result instanceof Promise) {
                            result.then(v => {resolve(v)}, r => {reject(r)})
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                }
                // 调用回调函数 PromiseState
                if (this.PromiseState === 'fulfilled') {
                    callback(onResolved)
                }
                if (this.PromiseState === 'rejected') {
                    callback(onRejected)
                }
                if (this.PromiseState === 'pending') {
                    // 保存回调函数
                    this.callbacks.push({
                        onResolved: function() {
                            callback(onResolved)
                        },
                        onRejected: function() {
                            callback(onRejected)
                        }
                    })
                }
            })
        }

        catch(onRejected) {
            return this.then(undefined, onRejected)
        }

        resolve = function(value) {
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(v => {resolve(v)}, r => {reject(r)})
                } else {
                    resolve(value)
                }
            })
        }

        static reject(reason) {
            return new Promise((resolve, reject) => {
                reject(reason)
            })
        }

        static all(promises) {
            return new Promise((resolve, reject) => {
                let count = 0
                let arr = []
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(v => {
                        count++
                        // 将成功的promise放在数组里，注意是按顺序放，i要对准
                        // 不要arr.push(v),因为各个promise返回的顺序不一定是原来的顺序
                        arr[i] = v
                        if (count === promises.length) {
                            resolve(v)
                        }
                    }, r => {
                        reject(r)
                    })
                }
            })
        }

        static race(promises) {
            return new Promise((resolve, reject) => {
                for (let i = 0; i < promises.length; i++) {
                    promises[i].then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                }
            })
        }
    }
    return Promise
})